//package org.example.springaitest.util;
//
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.core.type.TypeReference;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import org.neo4j.driver.Driver;
//import org.neo4j.driver.Record;
//import org.neo4j.driver.Result;
//import org.neo4j.driver.Session;
//import org.springframework.ai.chat.client.ChatClient;
//import org.springframework.ai.document.Document;
//import org.springframework.ai.vectorstore.VectorStore;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.CommandLineRunner;
//import org.springframework.core.io.Resource;
//import org.springframework.stereotype.Component;
//
//import java.io.InputStream;
//import java.util.*;
//
//@Component
//public class ChunkImporter implements CommandLineRunner {
//
//    private final Driver driver;
//    private final ChatClient chatClient;
//    private final VectorStore vectorStore;
//    private final ObjectMapper mapper = new ObjectMapper();
//
//    @Value("classpath:/spring-ai-documents-neo4j-add.json")
//    private Resource chunkFile;
//
//    public ChunkImporter(Driver driver,
//                         ChatClient chatClient,
//                         @Qualifier("neo4jVectorStore") VectorStore vectorStore) {
//        this.driver = driver;
//        this.chatClient = chatClient;
//        this.vectorStore = vectorStore;
//    }
//
//    @Override
//    public void run(String... args) throws Exception {
//        System.out.println("开始导入文本块...");
//
//        // 1. 读取 JSON 文件中的 chunks
//        List<Chunk> chunks;
//        try (InputStream in = chunkFile.getInputStream()) {
//            chunks = mapper.readValue(in, new TypeReference<List<Chunk>>() {});
//        }
//
//        // 2. 逐个导入
//        for (Chunk chunk : chunks) {
//            importChunk(chunk);
//        }
//
//        System.out.println("全部 chunk 向量 + 图谱信息导入完成");
//    }
//
//    private void importChunk(Chunk chunk) {
//        try {
//            // Step 1: 使用 vectorStore.add() 创建 :Document:Vector 节点（主节点）
//            Document doc = Document.builder()
//                    .id(chunk.id())
//                    .text(chunk.content())
//                    .metadata(Map.of("source", "manual-import"))
//                    .build();
//
//            vectorStore.add(List.of(doc));
//            System.out.println("✅ 已创建主节点: Document(id=" + chunk.id() + ")");
//
//            // Step 2: 提取图谱信息（通过 LLM）
//            String prompt = """
//                    从下面文本中抽取实体与关系，仅返回纯 JSON：
//                    {
//                      "entities": [
//                        {"label": "Person", "name": "张三"}
//                      ],
//                      "relations": [
//                        {"start": "张三", "type": "负责", "end": "网银接口"}
//                      ]
//                    }
//                    文本：
//                    %s
//                    """.formatted(chunk.content());
//
//            String rawResponse = chatClient.prompt(prompt).call().content();
//            String cleanedJson = rawResponse.replaceAll("```json|```", "").trim();
//
//            GraphResult graphResult;
//            try {
//                graphResult = mapper.readValue(cleanedJson, GraphResult.class);
//            } catch (JsonProcessingException e) {
//                System.err.println("❌ JSON 解析失败，跳过图谱构建，文本: " + chunk.content());
//                System.err.println("响应内容: " + cleanedJson);
//                return;
//            }
//
//            // Step 3: 在 Neo4j 中创建实体和关系，并连接到 :Document:Vector 节点
//            try (Session session = driver.session()) {
//                session.writeTransaction(tx -> {
//                    // 3.1 创建实体节点，并连接到 Document 主节点
//                    if (graphResult.entities() != null) {
//                        for (Entity entity : graphResult.entities()) {
//                            if (entity.name() == null || entity.name().trim().isEmpty()) {
//                                System.err.println("跳过空实体: " + entity);
//                                continue;
//                            }
//
//                            tx.run("""
//                                    MERGE (d:Document:Vector {id: $docId})
//                                    MERGE (e:`%s` {name: $name})
//                                    MERGE (d)-[:HAS_ENTITY]->(e)
//                                    """.formatted(entity.label()),
//                                    Map.of("docId", chunk.id(), "name", entity.name()));
//                        }
//                    }
//
//                    // 3.2 创建实体间的关系
//                    if (graphResult.relations() != null) {
//                        for (Relation relation : graphResult.relations()) {
//                            if (relation.start() == null || relation.start().trim().isEmpty() ||
//                                    relation.end() == null || relation.end().trim().isEmpty()) {
//                                System.err.println("跳过无效关系: " + relation);
//                                continue;
//                            }
//
//                            tx.run("""
//                                    MERGE (a {name: $start})
//                                    MERGE (b {name: $end})
//                                    MERGE (a)-[:`%s`]->(b)
//                                    """.formatted(relation.type()),
//                                    Map.of("start", relation.start(), "end", relation.end()));
//                        }
//                    }
//
//                    return null;
//                });
//            }
//
//            System.out.println("🔗 已为 Document(id=" + chunk.id() + ") 添加图谱信息");
//
//        } catch (Exception e) {
//            throw new RuntimeException("导入 chunk 失败: " + chunk.id(), e);
//        }
//    }
//
//    // --- 数据模型 ---
//    record Chunk(String id, String content) {}
//    record GraphResult(List<Entity> entities, List<Relation> relations) {}
//    record Entity(String label, String name) {}
//    record Relation(String start, String type, String end) {}
//}